﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
#if !UNITY_EDITOR && UNITY_WSA
using System;
using System.Linq;
using Windows.Networking.Connectivity;
#endif
namespace Nijie.Network
{
    public class NetworkConnectionSettings : MonoBehaviour
    {
        [SerializeField, Header("是否自动建立连接")]
        bool autoConnect = true;
        [SerializeField, Header("连接等待时间"), Range(0, 5)]
        float maxTime = 2;
        [SerializeField, Header("当不是自动建立连接时，是否作为Host")]
        bool startAsHost = false;
        UNetworkDiscovery networkDiscovery;
        static bool running = false;
        Coroutine starting = null;
        // Use this for initialization
        void Start()
        {
            networkDiscovery = UNetworkDiscovery.Instance;
            starting = StartCoroutine(WaitForNetworkRunning());
        }
        private void Update()
        {
            if (autoConnect && running && !NetworkManager.singleton.isNetworkActive && networkDiscovery != null && starting == null)
            {
                NetworkManager.singleton.networkAddress = "localhost";
                networkDiscovery.Initialize();
                networkDiscovery.remoteSessions.Clear();
                networkDiscovery.broadcastInterval = networkDiscovery.BroadcastInterval;
                networkDiscovery.StartAsClient();
                starting = StartCoroutine(WaitForNetworkRunning());
            }
            if (!autoConnect && !startAsHost && running && !NetworkManager.singleton.isNetworkActive && networkDiscovery != null)
            {
                if (connectedIp != null && !connectedIp.Equals(""))
                {
                    if (starting == null)
                    {
                        NetworkManager.singleton.networkAddress = "localhost";
                        networkDiscovery.Initialize();
                        networkDiscovery.remoteSessions.Clear();
                        networkDiscovery.broadcastInterval = networkDiscovery.BroadcastInterval;
                        networkDiscovery.StartAsClient();
                        starting = StartCoroutine(WaitForNetworkRunning());
                    }
                    else
                    {
                        UNetworkDiscovery.SessionInfo session = null;
                        foreach (KeyValuePair<string, UNetworkDiscovery.SessionInfo> keyValue in networkDiscovery.remoteSessions)
                            if (keyValue.Value.SessionIp.Equals(connectedIp))
                                session = keyValue.Value;
                        if (session != null)
                        {
                            JoinSession(session);
                            StopCoroutine(starting);
                            starting = null;
                        }
                        //else
                        //    starting = StartCoroutine(WaitForNetworkRunning());
                    }
                }
            }
        }
        IEnumerator WaitForNetworkRunning()
        {
            Debug.LogWarning("Init NetworkDiscovery!");
            //SyncManager.Instance.gameObject.SetActive(false);
            while (!networkDiscovery.running)
            {
                yield return new WaitForEndOfFrame();
            }
            Debug.LogWarning("NetworkDiscovery inited!");
            if (autoConnect)
            {
                Debug.LogWarning("Start Finding Host.");
                float time = 0;
                bool joined = false;
                while (time < maxTime && !joined)
                {
                    yield return new WaitForEndOfFrame();
                    time += Time.deltaTime;
                    //Debug.LogWarning("Has been finding for " + time + " seconds!");
                    foreach (KeyValuePair<string, UNetworkDiscovery.SessionInfo> keyValue in networkDiscovery.remoteSessions)
                    {
                        Debug.LogWarning("Join to " + keyValue.Value.SessionIp);
                        networkDiscovery.JoinSession(keyValue.Value);
                        joined = true;
                        break;
                    }
                }
                if (!joined)
                {
                    Debug.LogWarning("No Host was found!");
                    networkDiscovery.StartHosting(SessionName);
                    Debug.LogWarning("Start as host!");
                }
            }
            else if (startAsHost)
                networkDiscovery.StartHosting(SessionName);
            running = true;
            starting = null;
            if (SyncManager.Instance.gameObject.activeSelf)
                SyncManager.Instance.OnEnable();
        }
        public static bool Running { get { return running; } }
        public static Dictionary<string, UNetworkDiscovery.SessionInfo> RemoteSessions { get { return UNetworkDiscovery.Instance.remoteSessions; } }
        static string connectedIp;
        public static void JoinSession(UNetworkDiscovery.SessionInfo session)
        {
            connectedIp = session.SessionIp;
            UNetworkDiscovery.Instance.JoinSession(session);
        }
        public static string SessionName { get { return string.Format("{0}@{1}", SystemInfo.deviceName, IPV4); } }
        public static string IPV4
        {
            get
            {
#if !UNITY_EDITOR && UNITY_WSA
            Guid? networkAdapterId = NetworkInformation.GetInternetConnectionProfile()?.NetworkAdapter?.NetworkAdapterId;
            return (networkAdapterId.HasValue ? NetworkInformation.GetHostNames().FirstOrDefault(hn => hn?.IPInformation?.NetworkAdapter.NetworkAdapterId == networkAdapterId)?.CanonicalName : null);
#else
                return UnityEngine.Network.player.ipAddress;
#endif
            }

        }
    }
}